package com.yangtu.nearbyshop.wx.web;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sun.org.apache.xpath.internal.operations.Or;
import com.yangtu.nearbyshop.core.util.ResponseUtil;
import com.yangtu.nearbyshop.db.domain.NearbyshopMerc;
import com.yangtu.nearbyshop.db.domain.NearbyshopOrder2;
import com.yangtu.nearbyshop.db.domain.NearbyshopRegion;
import com.yangtu.nearbyshop.db.domain.NearbyshopUser;
import com.yangtu.nearbyshop.db.service.NearbyshopMercService;
import com.yangtu.nearbyshop.db.service.NearbyshopOrderGoodsService;
import com.yangtu.nearbyshop.db.service.NearbyshopUserService;
import com.yangtu.nearbyshop.db.service.itf.INearbyshopOrderService;
import com.yangtu.nearbyshop.db.util.OrderUtil;
import com.yangtu.nearbyshop.wx.annotation.LoginUser;
import com.yangtu.nearbyshop.wx.service.GetRegionService;
import com.yangtu.nearbyshop.wx.util.WxResponseCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

/**
 * 用户提货点服务
 */
@RestController
@RequestMapping("/wx/merc")
@Validated
public class WxMercController extends GetRegionService {
	private final Logger logger = LoggerFactory.getLogger(WxMercController.class);

	@Autowired
	private NearbyshopMercService mercService;

    @Autowired
    private NearbyshopUserService userService;

    @Autowired
    private NearbyshopOrderGoodsService orderGoodsService;

    @Autowired
    private INearbyshopOrderService orderService;

	private final static ArrayBlockingQueue<Runnable> WORK_QUEUE = new ArrayBlockingQueue<>(6);

	private final static RejectedExecutionHandler HANDLER = new ThreadPoolExecutor.CallerRunsPolicy();

	private static ThreadPoolExecutor executorService = new ThreadPoolExecutor(3, 6, 1000, TimeUnit.MILLISECONDS, WORK_QUEUE, HANDLER);


    /**
     * 查看指定门店信息
     *
     * @param userId  用户ID
     * @param mercNo  门店编号
     * @return 指定门店信息
     */
	@GetMapping("query")
	public Object queryMerc(@LoginUser Integer userId, @RequestParam String mercNo) {

        logger.info("用户所属门店信息查询，queryMerc入参userId={},mercNo={}", userId, mercNo);
		if (StringUtils.isEmpty(userId)) {
			return ResponseUtil.unlogin();
		}

		if (StringUtils.isEmpty(mercNo)){
			return ResponseUtil.fail(WxResponseCode.MERC_NO_EMPTY, "查询的门店编号为空");
		}
		NearbyshopMerc nearbyshopMerc = mercService.queryByMercNo(mercNo);
        if (nearbyshopMerc == null) {
            return ResponseUtil.fail(WxResponseCode.MERC_NO_EMPTY, "查询的门店编号为空");
        }
        List<NearbyshopRegion> regionList = getNearbyshopRegions();
        Map<String, Object> mercVo = new HashMap<>();

        Callable<String> provinceCallable = () -> regionList.stream().filter(region -> region.getId().equals(nearbyshopMerc.getProvinceId())).findAny().orElse(null).getName();
        Callable<String> cityCallable = () -> regionList.stream().filter(region -> region.getId().equals(nearbyshopMerc.getCityId())).findAny().orElse(null).getName();
        Callable<String> areaCallable = () -> regionList.stream().filter(region -> region.getId().equals(nearbyshopMerc.getAreaId())).findAny().orElse(null).getName();
        FutureTask<String> provinceNameCallableTask = new FutureTask<>(provinceCallable);
        FutureTask<String> cityNameCallableTask = new FutureTask<>(cityCallable);
        FutureTask<String> areaNameCallableTask = new FutureTask<>(areaCallable);
        executorService.submit(provinceNameCallableTask);
        executorService.submit(cityNameCallableTask);
        executorService.submit(areaNameCallableTask);
        String detailedAddress = "";
        try {
            String province = provinceNameCallableTask.get();
            String city = cityNameCallableTask.get();
            String area = areaNameCallableTask.get();
            String addr = nearbyshopMerc.getMercAddr();
            detailedAddress = province + city + area + " " + addr;
        }
        catch (Exception e) {
            e.printStackTrace();
        }

        int count = orderService.count(new QueryWrapper<NearbyshopOrder2>()
            .eq("merc_no",mercNo)
            .eq("user_id",userId)
            .in("order_status", OrderUtil.STATUS_PAY,OrderUtil.STATUS_PURCHASE,
                    OrderUtil.STATUS_SHIP,OrderUtil.STATUS_TAKEN,OrderUtil.STATUS_CONFIRM,
                    OrderUtil.STATUS_REFUND,OrderUtil.STATUS_REFUND_CONFIRM,
                    OrderUtil.STATUS_AUTO_CONFIRM));

        mercVo.put("detailedAddress", detailedAddress);
        mercVo.put("mercName", nearbyshopMerc.getMercName());
        mercVo.put("avaterUrl", nearbyshopMerc.getAvatar());
        mercVo.put("nickName", nearbyshopMerc.getNickname());
        mercVo.put("mobile", nearbyshopMerc.getMobile());
        mercVo.put("saleNum", orderGoodsService.getMercSaleNum(mercNo));
        mercVo.put("fansNum", userService.getFansNum(mercNo));
        mercVo.put("orderNum", count);
        return ResponseUtil.ok(mercVo);
	}

    /**
     * 用户附近门店列表
     *
     * @param longitude  用户当前经度
     * @param latitude  用户当前纬度
     * @return 附近门店列表列表
     */
    @GetMapping("list")
    public Object list(@RequestParam String longitude,@RequestParam String latitude, String mercNm) {

        logger.info("用户附近门店信息查询，附近门店用户位置longitude={},latitude={}", longitude, latitude);
        if (longitude == null) {
            return ResponseUtil.fail(WxResponseCode.MERC_LONGITUDE_EMPTY, "用户经度为空");
        }

        if (latitude == null){
            return ResponseUtil.fail(WxResponseCode.MERC_LATITUDE_EMPTY, "用户维度为空");
        }
        List<Map<String, String>> mercList = mercService.queryNearbyMercList(longitude, latitude, mercNm);
        List<NearbyshopRegion> regionList = getNearbyshopRegions();
        Map<String, String> mercVo;
        List<Map<String, String>> mercVoList = new ArrayList<>();
        for (Map<String, String> mercMap: mercList){
            mercVo = new HashMap<>();
            Callable<String> provinceCallable = () -> regionList.stream().filter(region -> region.getId().equals(mercMap.get("province_id"))).findAny().orElse(null).getName();
            Callable<String> cityCallable = () -> regionList.stream().filter(region -> region.getId().equals(mercMap.get("city_id"))).findAny().orElse(null).getName();
            Callable<String> areaCallable = () -> regionList.stream().filter(region -> region.getId().equals(mercMap.get("area_id"))).findAny().orElse(null).getName();
            FutureTask<String> provinceNameCallableTask = new FutureTask<>(provinceCallable);
            FutureTask<String> cityNameCallableTask = new FutureTask<>(cityCallable);
            FutureTask<String> areaNameCallableTask = new FutureTask<>(areaCallable);
            executorService.submit(provinceNameCallableTask);
            executorService.submit(cityNameCallableTask);
            executorService.submit(areaNameCallableTask);
            String detailedAddress = "";
            try {
                String province = provinceNameCallableTask.get();
                String city = cityNameCallableTask.get();
                String area = areaNameCallableTask.get();
                String addr = mercMap.get("merc_addr");
                detailedAddress = province + city + area + addr;
            }
            catch (Exception e) {
                e.printStackTrace();
            }
            mercVo.put("detailedAddress", detailedAddress);
            mercVo.put("mercName", mercMap.get("merc_name"));
            mercVo.put("mercNo", mercMap.get("merc_no"));
            mercVo.put("latitude", mercMap.get("latitude"));
            mercVo.put("longitude", mercMap.get("longitude"));
            mercVo.put("distance", mercMap.get("distance"));

            mercVoList.add(mercVo);
        }

        logger.info("附近门店信息：{}", mercVoList);

        return ResponseUtil.ok(mercVoList);
    }

    /**
     * 用户绑定提货门店
     *
     * @param userId  用户ID
     * @param mercNo  门店编号
     * @return 指定门店信息
     */
    @GetMapping("bind")
    public Object bindMerc(@LoginUser Integer userId, @RequestParam String mercNo) {

        logger.info("用户绑定指定门店，bindMerc入参userId={},mercNo={}", userId, mercNo);
        if (userId == null) {
            return ResponseUtil.unlogin();
        }

        if (mercNo == null){
            return ResponseUtil.fail(WxResponseCode.MERC_NO_EMPTY, "绑定的门店编号有误");
        }
        NearbyshopMerc nearbyshopMerc = mercService.queryByMercNo(mercNo);

        if (nearbyshopMerc == null) {
            return ResponseUtil.fail(WxResponseCode.MERC_NO_NOT_EXIST, "绑定的门店编号有误");
        }

        NearbyshopUser nearbyshopUser = userService.findById(userId);

        nearbyshopUser.setMercNo(mercNo);

        if (userService.updateById(nearbyshopUser) == 0) {
            return ResponseUtil.updatedDataFailed();
        }

        return ResponseUtil.ok();
    }
}
